﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	internal class AnalysisStruct
	{
		public static void SignRegion(Autodesk.Revit.DB.Document doc, List<RectStruct> lstRect, Category lineCategory)
		{
			foreach (RectStruct rectStruct in lstRect)
			{
				int num = 1;
				foreach (Curve curve in rectStruct.LstCurve)
				{
					doc.GetTextNode(doc.ActiveView, AnalysisStruct.GetCenterPoint(curve), new XYZ(1.0, 0.0, 0.0), new XYZ(0.0, 1.0, 0.0), 3.0, (Autodesk.Revit.DB.TextAlignFlags)1152, rectStruct.nId.ToString() + ":" + num);
					GroundStorehouseNozzle.DrawCurve(doc.ActiveView, doc, curve, lineCategory);
					num++;
				}
			}
		}

		private static XYZ GetCenterPoint(Curve lst)
		{
			new XYZ(0.0, 0.0, 0.0);
			XYZ endPoint = lst.GetEndPoint(0);
			XYZ endPoint2 = lst.GetEndPoint(1);
			return (endPoint + endPoint2) / 2.0;
		}

		public static void Merge(List<RectStruct> lstRect, out List<RectStruct> listOut)
		{
			listOut = new List<RectStruct>();
			int num = lstRect.Count;
			List<RectStruct> list = new List<RectStruct>();
			List<int> list2 = new List<int>();
			List<RectStruct> list3 = new List<RectStruct>();
			foreach (RectStruct rectStruct in lstRect)
			{
				if (!rectStruct.blMerge)
				{
					list3.Add(rectStruct);
				}
				else
				{
					int num2 = 1;
					for (int i = 0; i < rectStruct.nSign.Count; i++)
					{
						if (rectStruct.nSign[i] == 1)
						{
							switch (num2)
							{
							case 1:
							{
								int upRect = rectStruct.UpRect;
								RectStruct rectStruct2 = AnalysisStruct.MergeRectStruct(list2, lstRect, upRect, rectStruct, num);
								if (rectStruct2 != null)
								{
									AnalysisStruct.UpdateRectStruct(1, upRect, rectStruct2, rectStruct, lstRect, ref list2);
									num++;
									list.Add(rectStruct2);
								}
								break;
							}
							case 2:
							{
								int downRect = rectStruct.DownRect;
								RectStruct rectStruct2 = AnalysisStruct.MergeRectStruct(list2, lstRect, downRect, rectStruct, num);
								if (rectStruct2 != null)
								{
									AnalysisStruct.UpdateRectStruct(2, downRect, rectStruct2, rectStruct, lstRect, ref list2);
									num++;
									list.Add(rectStruct2);
								}
								break;
							}
							case 3:
							{
								int leftRect = rectStruct.LeftRect;
								RectStruct rectStruct2 = AnalysisStruct.MergeRectStruct(list2, lstRect, leftRect, rectStruct, num);
								if (rectStruct2 != null)
								{
									AnalysisStruct.UpdateRectStruct(3, leftRect, rectStruct2, rectStruct, lstRect, ref list2);
									num++;
									list.Add(rectStruct2);
								}
								break;
							}
							case 4:
							{
								int rightRect = rectStruct.RightRect;
								RectStruct rectStruct2 = AnalysisStruct.MergeRectStruct(list2, lstRect, rightRect, rectStruct, num);
								if (rectStruct2 != null)
								{
									AnalysisStruct.UpdateRectStruct(4, rightRect, rectStruct2, rectStruct, lstRect, ref list2);
									num++;
									list.Add(rectStruct2);
								}
								break;
							}
							}
						}
						num2++;
					}
				}
			}
			using (List<int>.Enumerator enumerator2 = list2.GetEnumerator())
			{
				while (enumerator2.MoveNext())
				{
					int item = enumerator2.Current;
					IEnumerable<RectStruct> source = from n in lstRect
					where n.nId == item
					select n;
					if (source.Count<RectStruct>() > 0)
					{
						lstRect.Remove(source.First<RectStruct>());
					}
				}
			}
			if (list3.Count == lstRect.Count)
			{
				listOut = lstRect;
				return;
			}
			lstRect.AddRange(list);
			AnalysisStruct.Merge(lstRect, out listOut);
		}

		private static RectStruct MergeRectStruct(List<int> lstRectDel, List<RectStruct> lstRect, int id, RectStruct item, int TotalId)
		{
			if (lstRectDel.Contains(item.nId))
			{
				return null;
			}
			IEnumerable<RectStruct> source = from n in lstRect
			where n.nId == id
			select n;
			if (source.Count<RectStruct>() > 0)
			{
				List<Curve> list = new List<Curve>();
				list.AddRange(source.First<RectStruct>().LstCurve);
				list.AddRange(item.LstCurve);
				List<Curve> list2 = GroundStorehouseNozzle.MergeCurve(list);
				return new RectStruct
				{
					nId = TotalId + 1,
					blRect = GroundStorehouseNozzle.GetBlRect(list2),
					blMerge = GroundStorehouseNozzle.GetBlLess(list2)
				};
			}
			return null;
		}

		private static void UpdateRectStruct(int NorId, int MergeId, RectStruct structRectMerge, RectStruct structRect, List<RectStruct> lstRect, ref List<int> lstRectDel)
		{
			lstRectDel = new List<int>();
			lstRectDel.Add(structRect.nId);
			lstRectDel.Add(MergeId);
			IEnumerable<RectStruct> source = from n in lstRect
			where n.nId == MergeId
			select n;
			if (source.Count<RectStruct>() == 0)
			{
				return;
			}
			RectStruct rectStruct = source.First<RectStruct>();
			if (NorId == 1)
			{
				rectStruct.DownRect = structRectMerge.nId;
				structRectMerge.UpRect = rectStruct.nId;
			}
			if (NorId == 2)
			{
				rectStruct.UpRect = structRectMerge.nId;
				structRectMerge.DownRect = rectStruct.nId;
			}
			if (NorId == 3)
			{
				rectStruct.RightRect = structRectMerge.nId;
				structRectMerge.LeftRect = rectStruct.nId;
			}
			if (NorId == 4)
			{
				rectStruct.LeftRect = structRectMerge.nId;
				structRectMerge.RightRect = rectStruct.nId;
			}
		}

		private int Merge1(List<RectStruct> lstRect, RectStruct item, int index)
		{
			List<Curve> lstCurve = item.LstCurve;
			new List<Curve>();
			int result = 0;
			foreach (RectStruct rectStruct in lstRect)
			{
				if (rectStruct.nId == index)
				{
					List<Curve> lstCurve2 = rectStruct.LstCurve;
					result = rectStruct.nId;
					break;
				}
			}
			return result;
		}

		public static List<RectStruct> AnalysisRectRegions(List<List<Curve>> lstRoomRegion)
		{
			List<RectStruct> list = AnalysisStruct.AnalysisRegions(lstRoomRegion);
			foreach (RectStruct rectStruct in list)
			{
				if (rectStruct.blRect && rectStruct.blMerge)
				{
					rectStruct.UpRect = AnalysisStruct.GetNRect(rectStruct.nId, rectStruct.LstCurve[0], list);
					rectStruct.DownRect = AnalysisStruct.GetNRect(rectStruct.nId, rectStruct.LstCurve[1], list);
					rectStruct.LeftRect = AnalysisStruct.GetNRect(rectStruct.nId, rectStruct.LstCurve[2], list);
					rectStruct.RightRect = AnalysisStruct.GetNRect(rectStruct.nId, rectStruct.LstCurve[3], list);
				}
			}
			return list;
		}

		private static int GetNRect(int id, Curve rect, List<RectStruct> temp)
		{
			foreach (RectStruct rectStruct in temp)
			{
				if (id != rectStruct.nId && AnalysisStruct.GetIDRect(rectStruct.LstCurve, rect))
				{
					return rectStruct.nId;
				}
			}
			return 0;
		}

		private static bool GetIDRect(List<Curve> temp, Curve rect)
		{
			YJKLine hyline = new YJKLine(rect.GetEndPoint(0), rect.GetEndPoint(1));
			foreach (Curve curve in temp)
			{
				YJKLine hyline2 = new YJKLine(curve.GetEndPoint(0), curve.GetEndPoint(1));
				if (hyline.IsParallel(hyline2.Line) && ((hyline.StartPoint.IsAlmostEqualTo(hyline2.StartPoint, 0.0001) && hyline.EndPoint.IsAlmostEqualTo(hyline2.EndPoint, 0.0001)) || (hyline.EndPoint.IsAlmostEqualTo(hyline2.StartPoint, 0.0001) && hyline.StartPoint.IsAlmostEqualTo(hyline2.EndPoint, 0.0001))))
				{
					return true;
				}
			}
			return false;
		}

		private static List<RectStruct> AnalysisRegions(List<List<Curve>> lstRoomRegion)
		{
			List<RectStruct> list = new List<RectStruct>();
			int num = 0;
			foreach (List<Curve> list2 in lstRoomRegion)
			{
				RectStruct rectStruct = new RectStruct();
				rectStruct.nId = num++;
				rectStruct.blRect = GroundStorehouseNozzle.GetBlRect(list2);
				if (rectStruct.blRect)
				{
					rectStruct.blMerge = GroundStorehouseNozzle.GetBlLess(list2);
					List<Curve> lstCurve = new List<Curve>();
					rectStruct.nSign = AnalysisStruct.AnaUDLR(list2, out lstCurve);
					rectStruct.LstCurve = lstCurve;
				}
				else
				{
					rectStruct.LstCurve = list2;
					rectStruct.blMerge = false;
					rectStruct.nSign = new List<int>
					{
						0,
						0,
						0,
						0
					};
				}
				rectStruct.UpRect = 0;
				rectStruct.DownRect = 0;
				rectStruct.LeftRect = 0;
				rectStruct.RightRect = 0;
				list.Add(rectStruct);
			}
			return list;
		}

		private static List<int> AnaUDLR(List<Curve> lst, out List<Curve> lstOut)
		{
			lstOut = new List<Curve>();
			List<int> list = new List<int>();
			bool flag = false;
			List<Curve> list2 = GroundStorehouseNozzle.SortListCurve(lst, out flag);
			double num = 7.8740157480314954;
			if (list2[3].GetEndPoint(0).DistanceTo(list2[3].GetEndPoint(1)) <= num)
			{
				list.Add(1);
			}
			else
			{
				list.Add(0);
			}
			if (list2[1].GetEndPoint(0).DistanceTo(list2[1].GetEndPoint(1)) <= num)
			{
				list.Add(1);
			}
			else
			{
				list.Add(0);
			}
			if (list2[0].GetEndPoint(0).DistanceTo(list2[0].GetEndPoint(1)) <= num)
			{
				list.Add(1);
			}
			else
			{
				list.Add(0);
			}
			if (list2[2].GetEndPoint(0).DistanceTo(list2[2].GetEndPoint(1)) <= num)
			{
				list.Add(1);
			}
			else
			{
				list.Add(0);
			}
			lstOut.Add(list2[0]);
			lstOut.Add(list2[2]);
			lstOut.Add(list2[3]);
			lstOut.Add(list2[1]);
			return list;
		}
	}
}
